package com.ibm.ops.conf;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.ibm.ops.exception.InvalidPropertiesException;
import com.ibm.ops.exception.NoPropConfigurationException;

public class ProjectConfiguration {

	private static Logger logger = Logger.getLogger(ProjectConfiguration.class);
	
	private static final String RAW_LOG_PATH_KEY                   = "RAW_LOG_PATH";
	private static final String DESTINATION_PATH_KEY               = "DESTINATION_PATH";
	private static final String XLS_DESTINATION_PATH_KEY           = "XLS_DESTINATION_PATH";
	private static final String HUB_REPORT_NAME_KEY                = "HUB_REPORT_NAME";
	private static final String INFOSOURCE_REPORT_NAME_KEY         = "INFORSOURCE_REPORT_NAME";
	private static final String CIR_REPORT_NAME_KEY                = "CIR_REPORT_NAME";
	private static final String FODS_REPORT_NAME_KEY               = "FODS_REPORT_NAME";
	private static final String FODS_REJECT_REPORT_NAME_KEY        = "FODS_REJECT_REPORT_NAME";
	private static final String FODS_OUTOF_SEN_REPORT_NAME_KEY     = "FODS_OUTOF_SEN_REPORT_NAME";
	private static final String FODS_NO_ORDER_REPORT_NAME_KEY      = "FODS_NO_ORDER_REPORT_NAME";
	private static final String FODS_EOD_REPORT_NAME_KEY           = "FODS_EOD_REPORT_NAME";
	private static final String FOOT_REPORT_NAME_KEY               = "FOOT_REPORT_NAME";
	
	
	private static final String DEFAULT_CFG_PATH                   = "cfg\\conf.properties";
	
	
	private ProjectConfigurationDomain domain = null;
	
	private static ProjectConfiguration instance = null;

	private ProjectConfiguration(String cfg_file_path) throws NoPropConfigurationException, InvalidPropertiesException{
		
		logger.debug("start initlize projectconfiguration.");		
		//load properties here
		Properties prop = new Properties();
		File file = new File(cfg_file_path);
		try {
			if(file.exists() == false){
				throw new NoPropConfigurationException();
			} 
			prop.load(new FileInputStream(file));
			
			domain = new ProjectConfigurationDomain();
			domain.detination_path = prop.getProperty(DESTINATION_PATH_KEY,null);
			domain.xls_destination_path = prop.getProperty(XLS_DESTINATION_PATH_KEY,null);
			domain.hub_report_name = prop.getProperty(HUB_REPORT_NAME_KEY,null);
			domain.infosource_report_name = prop.getProperty(INFOSOURCE_REPORT_NAME_KEY,null);
			domain.cir_report_name = prop.getProperty(CIR_REPORT_NAME_KEY,null);
			domain.fods_report_name = prop.getProperty(FODS_REPORT_NAME_KEY,null);
			domain.raw_log_path = prop.getProperty(RAW_LOG_PATH_KEY,null);
			domain.foot_report_name = prop.getProperty(FOOT_REPORT_NAME_KEY,null);
			domain.fods_reject_report_name = prop.getProperty(FODS_REJECT_REPORT_NAME_KEY,null);
			domain.fods_outof_seq_report_name = prop.getProperty(FODS_OUTOF_SEN_REPORT_NAME_KEY,null);
			domain.fods_noorder_report_name = prop.getProperty(FODS_NO_ORDER_REPORT_NAME_KEY,null);
			domain.fods_eod_report_name = prop.getProperty(FODS_EOD_REPORT_NAME_KEY,null);
			domain.foot_report_name = prop.getProperty(FOOT_REPORT_NAME_KEY,null);
			domain.validate();
		} catch (FileNotFoundException e) {
			throw new NoPropConfigurationException();
		} catch (IOException e) {
			throw new NoPropConfigurationException();
		}
	}
	
	public synchronized static ProjectConfiguration getInstance() throws NoPropConfigurationException, InvalidPropertiesException{
		if(instance == null){
			instance = new ProjectConfiguration(DEFAULT_CFG_PATH);
		}
		return instance;
	}
	
	/**
	 * For test
	 * @param cfgPath
	 * @return
	 * @throws NoPropConfigurationException
	 * @throws InvalidPropertiesException 
	 */
	public synchronized static ProjectConfiguration getInstance(String cfgPath) throws NoPropConfigurationException, InvalidPropertiesException{
		if(instance == null){
			instance = new ProjectConfiguration(cfgPath);
		}
		return instance;
	}
	
	public ProjectConfigurationDomain getProjectConfiguration(){
		return this.domain;
	}
	
	
	public static class ProjectConfigurationDomain{
		private String raw_log_path = "";
		private String detination_path = "";
		private String xls_destination_path = "";
		private String hub_report_name = "";
		private String infosource_report_name = "";		
		private String cir_report_name = "";
		private String fods_report_name = "";
		private String foot_report_name = "";
		private String fods_reject_report_name = "";
		private String fods_outof_seq_report_name = "";
		private String fods_noorder_report_name = "";
		private String fods_eod_report_name = "";
		
		public String getXls_destination_path() {
			return xls_destination_path;
		}
		public String getDetination_path() {
			return detination_path;
		}
		public String getHub_report_name() {
			return hub_report_name;
		}
		public String getInfosource_report_name() {
			return infosource_report_name;
		}
		public String getCir_report_name() {
			return cir_report_name;
		}
		public String getFods_report_name() {
			return fods_report_name;
		}
		public String getRaw_log_path() {
			return raw_log_path;
		}
		public String getFoot_report_name() {
			return foot_report_name;
		}
		public String getFods_reject_report_name() {
			return fods_reject_report_name;
		}
		public String getFods_outof_seq_report_name() {
			return fods_outof_seq_report_name;
		}
		public String getFods_noorder_report_name() {
			return fods_noorder_report_name;
		}
		public String getFods_eod_report_name() {
			return fods_eod_report_name;
		}
		private void validate() throws InvalidPropertiesException{
			//check raw log path
			if(this.raw_log_path == null){
				throw new InvalidPropertiesException("Can not get the raw log path.");
			}else{
				File file = new File(this.raw_log_path);
				if(file.exists() == false){
					throw new InvalidPropertiesException("Raw log path is not exists, please check it. " + this.raw_log_path);
				}
				if(file.isFile() == false){
					throw new InvalidPropertiesException("Raw log is not a valid file, please check it. " + this.raw_log_path);
				}			
			}
			//check destination path
			if(this.detination_path == null){
				throw new InvalidPropertiesException("Can not get the destination path.");
			}else{
				File file = new File(this.detination_path);
				if(file.exists() == false){
					throw new InvalidPropertiesException("Destination path is not exists, please create it first. " + this.detination_path);
				}
				if(file.isDirectory() == false){
					throw new InvalidPropertiesException("Destination path is not a valid dictionary, please check it first. " + this.detination_path);
				}			
			}
			
			//check hub report name
			if(this.hub_report_name == null){
				throw new InvalidPropertiesException("Can not get the hub report name.");
			}			
			//check inforsource report name
			if(this.infosource_report_name == null){
				throw new InvalidPropertiesException("Can not get the inforsouce report name.");
			}
			//check cir report name
			if(this.cir_report_name == null){
				throw new InvalidPropertiesException("Can not get the cir report name.");
			}
			//check fods report name
			if(this.fods_report_name == null){
				throw new InvalidPropertiesException("Can not get the fods report name.");
			}
			//check fods reject report name
			if(this.fods_reject_report_name == null){
				throw new InvalidPropertiesException("Can not get the fods reject report name.");
			}
			//check fods out of seq report name
			if(this.fods_outof_seq_report_name == null){
				throw new InvalidPropertiesException("Can not get the fods out of seq report name.");
			}
			//check fods no order report name
			if(this.fods_noorder_report_name == null){
				throw new InvalidPropertiesException("Can not get the fods no order report name.");
			}
			//check fods eod report name
			if(this.fods_eod_report_name == null){
				throw new InvalidPropertiesException("Can not get the fods eod report name.");
			}
			//check foot report name
			if(this.foot_report_name == null){
				throw new InvalidPropertiesException("Can not get the foot report name.");
			}
			
		}
		@Override
		public String toString() {
			return "ProjectConfigurationDomain [raw_log_path=" + raw_log_path
					+ ", detination_path=" + detination_path
					+ ", xls_destination_path=" + xls_destination_path
					+ ", hub_report_name=" + hub_report_name
					+ ", infosource_report_name=" + infosource_report_name
					+ ", cir_report_name=" + cir_report_name
					+ ", fods_report_name=" + fods_report_name
					+ ", foot_report_name=" + foot_report_name
					+ ", fods_reject_report_name=" + fods_reject_report_name
					+ ", fods_outof_seq_report_name="
					+ fods_outof_seq_report_name
					+ ", fods_noorder_report_name=" + fods_noorder_report_name
					+ ", fods_eod_report_name=" + fods_eod_report_name + "]";
		}
		
			
	}
	
	public static void main(String[] args){
		ProjectConfigurationDomain domain;
		try {
			domain = ProjectConfiguration.getInstance(DEFAULT_CFG_PATH).getProjectConfiguration();
			System.out.println(domain);
		} catch (NoPropConfigurationException e) {
			e.printStackTrace();
		} catch (InvalidPropertiesException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
}
